package cn.kgc.controller;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.kgc.entity.Depts;
import cn.kgc.entity.Users;
import cn.kgc.form.DeptsAddForm;
import cn.kgc.form.DeptsUpdateForm;
import cn.kgc.service.DeptsService;
import cn.kgc.service.UsersService;
import cn.kgc.util.resultutil.ResultConstant;
import cn.kgc.util.resultutil.exception.HttpException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * @author YC
 */
@RestController
@RequestMapping("/depts")
@Api(tags = "部门管理接口")
@Validated
@Slf4j
@CrossOrigin
public class DeptsController {

    @Resource
    private DeptsService deptsService;
    @Resource
    private UsersService usersService;

    /**
     * 查询全部数据
     *
     * @return List<Depts>
     */
    @PreAuthorize("hasAuthority('depts:list')")
    @GetMapping("/list")
    @ApiOperation(value = "查询所有数据")
    @Cacheable(value = "depts", key = "#root.methodName")
    public List<Depts> selectAll() {
        return deptsService.list();
    }

    /**
     * 根据条件查询数据
     *
     * @param map 查询条件
     * @return List<Depts>
     */
    @GetMapping("/list2")
    @ApiOperation(value = "条件查询数据")
    public List<Depts> selectAll2(@RequestBody Map<String, Object> map) {
        String deptName = MapUtil.getStr(map, "deptName");
        LambdaQueryWrapper<Depts> wrapper = new LambdaQueryWrapper<>();
        wrapper.likeRight(StrUtil.isNotBlank(deptName), Depts::getDeptName, deptName);
        return deptsService.list(wrapper);
    }

    @GetMapping("/detail/{id}")
    @ApiOperation(value = "根据ID查看详细信息")
    @Cacheable(value = "depts", key = "#root.methodName + #id")
    public Depts detail(@PathVariable Integer id) {
        return deptsService.getById(id);
    }

    @DeleteMapping("/delete/{id}")
    @ApiOperation(value = "根据主键删除")
    @ApiImplicitParam(name = "id", value = "主键", paramType = "path", dataType = "string")
    @CrossOrigin
    public boolean delete(@PathVariable Integer id) {
        // 验证部门是否有负责人
        return deptsService.removeById(id);
    }

    @PostMapping("/save")
    @ApiOperation(value = "新增部门信息")
    @CacheEvict(value = "depts", key = "'selectAll'")
    public boolean save(@Validated @RequestBody DeptsAddForm form) {
        // 验证部门名称是否重复
        checkDeptName(form.getDeptName());
        // 验证部门负责人是否存在
        Users users = null;
        if (form.getUserId() != 0) {
            users = checkDeptBoss(form.getUserId());
        }
        // 新增逻辑
        Depts depts = new Depts();
        BeanUtils.copyProperties(form, depts);
        if (users != null) {
            depts.setUserEmail(users.getUserEmail());
            depts.setUserName(users.getUserName());
        }
        return deptsService.save(depts);
    }

    @PostMapping("/update")
    @ApiOperation(value = "更新部门信息")
    @Caching(evict = {
            @CacheEvict(value = "depts", key = "'detail' + #form.id"),
            @CacheEvict(value = "depts", key = "'selectAll'")
    })
    public boolean update(@RequestBody DeptsUpdateForm form) {
        // TODO 验证部门名称是否重复
        // 验证部门负责人是否存在
        Users users = null;
        if (form.getUserId() != 0) {
            users = checkDeptBoss(form.getUserId());
        }
        Depts depts = deptsService.getById(form.getId());
        BeanUtils.copyProperties(form, depts);
        if (users != null) {
            depts.setUserName(users.getUserName());
            depts.setUserEmail(users.getUserEmail());
        } else {
            depts.setUserId(0);
            depts.setUserName("");
            depts.setUserEmail("");
        }
        return deptsService.updateById(depts);
    }


    //==================================== 接口中使用的自定义方法 ===================================

    /**
     * 验证部门负责人是否存在
     */
    private Users checkDeptBoss(Integer userId) {
        Users users = usersService.getById(userId);
        if (users == null) {
            throw new HttpException(ResultConstant.DEPT_UPDATE_ERROR_NOT_EXISTS);
        }
        return users;
    }

    /**
     * 验证部门名称是否重复
     */
    private void checkDeptName(String deptName) {
        LambdaQueryWrapper<Depts> wrapper = new
                LambdaQueryWrapper<>();
        wrapper.eq(Depts::getDeptName, deptName);
        if (deptsService.count(wrapper) > 0) {
            throw new
                    HttpException(ResultConstant.DEPT_UPDATE_ERROR_REPEAT);
        }
    }

}
